package com.woniuedu.search.direct;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.woniuedu.search.entity.*;
import com.woniuedu.search.mapper.MessageMapper;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;

/**
 * @author futao
 * @date 2020/3/31.
 */
@Component
public class KillSender<T> {
    @Resource
    RabbitMQConfirm rabbitMQConfirm;

    @Resource
    RabbitMQReturns rabbitMQReturns;

    /**
     * 消息的最大重试次数
     */
    @Value("${app.rabbitmq.retry.max-retry-times}")
    private int maxRetryTimes;

    /**
     * 每次重试时间间隔
     */
    @Value("${app.rabbitmq.retry.retry-interval}")
    private Duration retryInterval;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Autowired(required = false)
    private MessageMapper messageMapper;


    public void send(T t,String userExchangeName,String key,String type) {
        String id = UUID.randomUUID().toString();
        Messages messages = com.woniuedu.search.entity.Messages.builder()
                .id(id)
                .msgData(JSON.toJSONString(t))
                .exchangeName(userExchangeName)
                .routingKey(key)
                //下次重试时间
                .nextRetryDateTime(LocalDateTime.now(ZoneOffset.ofHours(8)).plus(retryInterval))
                .retryTimes(0)
                .type(type)
                .build();
        //消息落库
        messageMapper.insert(
                messages
        );
        CorrelationData correlationData = new CorrelationData(messages.getId());
        // 设置confirm回调函数
        rabbitTemplate.setConfirmCallback(rabbitMQConfirm);
        // 设置return回调函数
        rabbitTemplate.setReturnCallback(rabbitMQReturns);
        //消息投递到MQ
        rabbitTemplate.convertAndSend(userExchangeName, key, messages, correlationData);
    }
    public void reSend(String correlationData) {
        Messages messages = messageMapper.selectById(correlationData);
        if (messages.getRetryTimes() < maxRetryTimes) {
            //进行重试
            rabbitTemplate.convertAndSend(messages.getExchangeName(),
                    messages.getRoutingKey(),
                    messages.getMsgData(),
                    new CorrelationData(messages.getId()));
            //更新DB消息状态
            messageMapper.update(null,
                    Wrappers.<Messages>lambdaUpdate()
                            .set(com.woniuedu.search.entity.Messages::getStatus, MessageStatusEnum.SENDING.getStatus())
                            .set(com.woniuedu.search.entity.Messages::getNextRetryDateTime, LocalDateTime.now(ZoneOffset.ofHours(8)).plus(retryInterval))
                            .set(com.woniuedu.search.entity.Messages::getRetryTimes, messages.getRetryTimes() + 1)
                            .eq(com.woniuedu.search.entity.Messages::getId, Integer.getInteger(correlationData))
            );
        }
    }
}